//Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Eas.WebCrawler.PlugIns.FileNamers;
using Eas.WebCrawler.Interfaces;

namespace Eas.WebCrawler.PlugIns.UrlProcessedHandlers {
    /// <summary>Handles <see cref="WebCrawlerEvents.UrlProcessed"/> events by saving out the response to a file.</summary>
    public class FileSavingUrlProcessedHandler : Eas.WebCrawler.PlugIns.UrlProcessedHandlers.UrlProcessedHandler {
        /// <summary>The base directory for saving files.</summary>
        /// <remarks>Backing field for the BaseSaveDirectory property.</remarks>
        /// <seealso cref="BaseSaveDirectory"/>
        private DirectoryInfo  _BaseSaveDirectory;

        /// <summary>The FileName to use when saving files.</summary>
        /// <remarks>Backing field for the FileNamer property.</remarks>
        /// <seealso cref="FileNamer"/>
        private FileNamer _FileNamer;
        /// <summary>Constructs the <see cref="FileSavingUrlProcessedHandler"/> from a base directory and file namer.</summary>
        /// <param name="baseSaveDirectory">The directory into which files should be saved.</param>
        /// <param name="fileNamer">A <see cref="FileNamer"/> to use to create a name for the file (usually from the uri of the request).</param>
        public FileSavingUrlProcessedHandler(DirectoryInfo baseSaveDirectory, FileNamer fileNamer) {
            _BaseSaveDirectory = baseSaveDirectory;
            _FileNamer = fileNamer;
        }

        /// <summary>The FileNames to use to create names when saving files.</summary>
        public FileNamer FileNamer {
            get { return _FileNamer; }
        }

        /// <summary>The base directory for saving files.</summary>
        public DirectoryInfo BaseSaveDirectory {
            get { return _BaseSaveDirectory; }
        }

        #region UrlProcessedHandler Members
        /// <summary>Handles the <see cref="WebCrawlerEvents.UrlProcessed"/> event fired by the web crawler when registered to do so.</summary>
        /// <param name="sender">The sender of the event.</param>
        /// <param name="argument">Details of the processed url.</param>
        /// <remarks>This implementation saves the response to disk.</remarks>
        public void UrlProcessed(object sender, Eas.WebCrawler.Interfaces.UrlCompletedEventArgs argument) {
            int blockSize=1000;
            string filename = System.IO.Path.Combine(_BaseSaveDirectory.ToString(), _FileNamer.GetFileName(argument.State.Request, _BaseSaveDirectory));
            if (argument.State.IsTextResponse) {
                using(System.IO.StreamWriter writer = new System.IO.StreamWriter(filename)){
                    using (System.IO.TextReader reader = argument.Storage.GetTextReader()) {
                        Eas.WebCrawler.Common.IO.StreamCopier.CopyTextStreams(reader, writer, blockSize);    
                    }
                }
            }
            else {
                using (System.IO.Stream stream = new System.IO.FileStream(filename, FileMode.Append) ) {
                    using (System.IO.BinaryWriter writer = new BinaryWriter(stream)) {
                        using (System.IO.BinaryReader reader = argument.Storage.GetBinaryReader()) {
                            Eas.WebCrawler.Common.IO.StreamCopier.CopyBinaryStreams(reader, writer, blockSize);
                        }
                    }
                }
            }
        }
        #endregion
    }
}
